import { InjectionKey, provide, inject, reactive, readonly as defineReadonly, defineComponent, UnwrapRef } from 'vue'

export interface CreateContextOptions {
  readonly?: boolean
  createProvider?: boolean
}

// 映射类型
type ShallowUnwrap<T> = {
  [P in keyof T]: UnwrapRef<T[P]>;
};

export function createContext<T>(context: any, key: InjectionKey<T> = Symbol(), options: CreateContextOptions = {}) {
  const { readonly = true, createProvider = false } = options
  const state = reactive(context)
  const provideData = readonly ? defineReadonly(state) : state
  !createProvider && provide(key, provideData)
  const Provide = createProvider ? defineComponent({
    name: 'Provide',
    inheritAttrs: false,
    setup(_, { slots }) {
      provide(key, provideData)
      return () => slots.default?.()
    }
  }) : null

  return { Provide, state }
}

export const useContext = <T>(key: InjectionKey<T> = Symbol(), defaultValue?: any, readonly = false): ShallowUnwrap<T> => {
  const state = inject(key, defaultValue || {})
  return readonly ? defineReadonly(state) : state
}
